﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ShoppingCart.WebApi.DataLayer;
using ShoppingCart.WebApi.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;

namespace ShoppingCart.WebApi.Controllers
{
    public class ItemsController : ApiController
    {
        RedisRepository repository = new RedisRepository();    

        // Add ShoppingCartItem
        // POST api/cart/5/items
        // To test: use Fiddler. 
        // send post to http://localhost:61563/api/cart/dXNlcjFAaG90bWFpbC5jb20=/items
        // using request body: {
        //                          "prodId" : 101,
        //                          "prodName" : "NoSQL Distilled",
        //                          "prodDesc" : "A brief guide to the emerging world of polyglot persistence.",
        //                          "prodPrice" : 24.99,
        //                          "quantity" : 1,
        //                          "imageUrl": "/productimages/101.png"
        //                      }
        //
        [HttpPost]
        public HttpResponseMessage Post(string encodedUserId, [FromBody]JObject json)
        {
            HttpResponseMessage response;

            try
            {
                if (json == null)
                    throw new ShoppingCartException("Wrong Input");

                ShoppingCartItem item = JsonConvert.DeserializeObject<ShoppingCartItem>(json.ToString());
                if (item.prodId == null || item.imageUrl == null || item.prodDesc == null || item.prodName == null || item.prodPrice <= 0 || item.quantity <= 0)
                    throw new ShoppingCartException("Wrong Input");

                //change Base64 encoding to user id
                //this could throw a FormatException if the encodedUserdId is not a properly formated Base64String, caught below
                String userId = Encoding.Default.GetString(Convert.FromBase64String(encodedUserId));

                repository.AddShoppingCartItem(userId, item);
                response = Request.CreateResponse(HttpStatusCode.Created);
                response.Headers.Location = new Uri(
                    Request.RequestUri + item.prodId
                );
            }
            catch (ShoppingCartException e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                        HttpStatusCode.BadRequest, e.ToString()
                );
            }
            catch (FormatException e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                        HttpStatusCode.Unauthorized, string.Format("UserId {0} is invalid.", encodedUserId)
                );
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                        HttpStatusCode.InternalServerError, e.ToString()
                );
            }

            return response;
        }


        // Update ShoppingCartItem
        // Put api/cart/5/items/1
        // To test: use Fiddler. 
        // send put to http://localhost:61563/api/cart/dXNlcjFAaG90bWFpbC5jb20=/items/5168bed10fdb8c0e7c671d32 
        // using request body: {
        //                          "prodId" : 101,
        //                          "prodName" : "NoSQL Distilled",
        //                          "prodDesc" : "A brief guide to the emerging world of polyglot persistence.",
        //                          "prodPrice" : 24.99,
        //                          "quantity" : 1,
        //                          "imageUrl": "/productimages/101.png"
        //                      }
        //        
        [HttpPut]
        public HttpResponseMessage Put(String encodedUserId, String prodId, [FromBody]JObject json)
        {
            HttpResponseMessage response;

            try
            {
                if (json == null)
                    throw new ShoppingCartException("Wrong Input");
                
                //change Base64 encoding to user id
                //this will throw a FormatException if the encodedUserId is not a properly formatted Base64Encoded string, caught below
                String userId = Encoding.Default.GetString(Convert.FromBase64String(encodedUserId));
                
                ShoppingCartItem item = JsonConvert.DeserializeObject<ShoppingCartItem>(json.ToString());
                if (prodId != item.prodId)
                    throw new ShoppingCartException("Wrong Input");
                
                if (item.prodId == null || item.imageUrl == null || item.prodDesc == null || item.prodName == null || item.prodPrice <= 0 || item.quantity <= 0)
                    throw new ShoppingCartException("Wrong Input");

                repository.AddShoppingCartItem(userId, item);

                response = Request.CreateResponse(HttpStatusCode.Created);
                response.Headers.Location = Request.RequestUri;
            }
            catch (ShoppingCartException e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                        HttpStatusCode.BadRequest, e.ToString()
                );
            }
            catch (FormatException e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                        HttpStatusCode.Unauthorized, string.Format("UserId {0} is invalid.", encodedUserId)
                );
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                        HttpStatusCode.InternalServerError, e.ToString()
                );
            }

            return response;
        }

        // DELETE api/cart/5/items/1
        // To test: use Fiddler. 
        // send delete to http://localhost:61563/api/cart/dXNlcjFAaG90bWFpbC5jb20=/items/5168bed10fdb8c0e7c671d32
        //
        public HttpResponseMessage Delete(String encodedUserId, String prodId)
        {
            HttpResponseMessage response;

            //change Base64 encoding to userid
            //this will throw a FormatException if the encodedUserId is not a properly formatted Base64Encoded string, caught below
            String userId = Encoding.Default.GetString(Convert.FromBase64String(encodedUserId));

            try
            {
                repository.DeleteShoppingCartItem(userId, prodId);
                response = Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (ShoppingCartException e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                    HttpStatusCode.NotFound,
                    string.Format("No matching record for User Id {0} and Product Id {1}.", userId, prodId)
                );
            }
            catch (FormatException e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                        HttpStatusCode.Unauthorized, string.Format("UserId {0} is invalid.", encodedUserId)
                );
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                    HttpStatusCode.InternalServerError,
                    e.ToString()
                );
            }

            return response;
        }
    }
}
